import copy
from typing import override
from .path import Path
from enum import Enum
from src.common.overload import overload

class ReservedCharacter(Enum):
    LESS_THAN = '<'
    GREATER_THAN = '>'
    COLON = ':'
    DOUBLE_QUOTATION_MARK = '"'
    FORWARD_SLASH = '/'
    BACKWARD_SLASH = '\\'
    PIPE = '|'
    QUESTION_MARK = '?'
    ASTERISK = '*'
    # 以上保留字符源自 https://learn.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file

class WindowsPath(Path):
    # DOS 风格的路径
    # https://learn.microsoft.com/zh-cn/dotnet/standard/io/file-path-formats
    def __init__(self, path: str):
        super().__init__(path)
        self.pathSeperator = '\\'
        self.volume = '' # 卷驱动器 例如 C
        self.volume, self.pathList = self.calc_path_list()

    def build_another(self, volume: str, pathList: list[str]) -> 'WindowsPath':
        another_ins = copy.deepcopy(self)
        another_ins.volume = volume
        another_ins.pathList = pathList
        another_ins.path = f'{volume}:{self.pathSeperator.join(pathList)}'
        return another_ins
    
    @override
    @staticmethod
    def CheckParameterLegal(path: str) -> bool:
        # https://learn.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file
        # TODO 一个不完全的实现，该方法判定为非法的一定非法，判定为合法的不一定合法
        test_ins = WindowsPath(path)
        if len(test_ins.pathList) == 0:
            return False
        for word in [test_ins.volume, *test_ins.pathList]:
            if len(word) > 255:
                return False
            for char in word:
                if char in ReservedCharacter:
                    return False
        return True
    
    def calc_path_list(self) -> tuple[str, list[str]]:
        a = self.path.split(':')
        # windows 路径也可以不显示指定卷驱动器
        # assert len(a) > 0, 'The path must contain a colon.'
        if len(a) == 1:
            return '', a[0].split(self.pathSeperator)
        else:
            return a[0], a[1].split(self.pathSeperator)
    
    def check_relative(self) -> bool:
        # 检查路径是否是相对路径
        if self.volume == '':
            # 未显示指定卷驱动器，为相对路径
            return True
        else:
            if self.pathList[0] == '':
                return False
            else:
                return True


    def get_parent_path(self) -> 'Path|None':
        # 获取父路径
        if self.volume == '':
            # 未显示指定卷驱动器，为相对路径
            if len(self.pathList) == 1:
                # 根路径没有父路径
                return None
            else:
                return WindowsPath('\\'.join(self.pathList[:-1]))
        else:
            if len(self.pathList) == 1:
                # 形如 'C:' 的路径没有父路径
                return None
            elif len(self.pathList) == 2 and self.pathList[1] == '' and self.pathList[0] == '':
                # 形如 'C:\\' 的路径没有父路径
                return None
            else:
                return WindowsPath(self.volume + ':' + '\\'.join(self.pathList[:-1]))

    def get_path(self) -> str:
        # 获取路径字符串
        return self.path